package com.juyu.miliao.api.service;


import com.juyu.miliao.api.constant.UserTypeEnum;
import com.juyu.miliao.api.dao.redis.QuestionAndAnswerInfoRedisDao;
import com.juyu.miliao.api.dao.redis.SecretLanguagePlanetInfoRedisDao;
import com.juyu.miliao.api.dao.redis.usercache.UserCacheVo;
import com.juyu.miliao.api.dao.redis.usercache.UserInfoCache;
import com.juyu.miliao.api.domain.QuestionAndAnswerInfo;
import com.juyu.miliao.api.domain.SecretLanguagePlanetInfo;
import com.juyu.miliao.api.domain.User;
import com.juyu.miliao.api.domain.vo.SecretLanguagePlanetVo;
import com.juyu.miliao.api.util.RandomUtil;
import com.juyu.miliao.common.constant.SecretLanguagePlanetErroCodeEnum;
import com.juyu.miliao.common.exception.SecretLanguagePlanetException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 密语星球service
 *
 * @author xuanqicheng
 * @create 2019-04-09:52
 */
@Service
@Slf4j
public class SecretLanguagePlanetService {

    private static final Integer NUMBERS = 5;
    @Autowired
    private QuestionAndAnswerInfoRedisDao questionAndAnswerInfoRedisDao;

    @Autowired
    private UserInfoCache userInfoCache;

    @Autowired
    private SecretLanguagePlanetInfoRedisDao secretLanguagePlanetInfoRedisDao;

    /**
     * 根据用户id获取展示列表
     *
     * @param userId
     * @param number 列表个数
     */
    public List<Map<String, Object>> getList(long userId, Integer number) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        List<String> list = questionAndAnswerInfoRedisDao.getQualityQuestionAndAnswerList();

        //获取此用户已偷听过的语音
        List<String> userList = secretLanguagePlanetInfoRedisDao.getListByUserId(userId);

        //去重
        list.removeAll(userList);

        //筛选返还内容
        if (list.size() > 0 && list.size() > number) {
            //随机获取指定大小的列表
            int[] randoms = RandomUtil.randomCommon(0, list.size(), number);
            for (int i = 0; i < randoms.length; i++) {
                int index = randoms[i] - 1;
                String questionId = list.get(index);
                getQuestionAndAnswerInfo(resultList, questionId);

            }
        } else if (list.size() > 0 && list.size() <= number) {
            //直接使用差集队列
            for (String questionId : list) {
                getQuestionAndAnswerInfo(resultList, questionId);
            }
        } else {
            //抛异常，提示没有可用的秘密
            String code = SecretLanguagePlanetErroCodeEnum.LIST_IS_EMPTY.getCode();

            String message = SecretLanguagePlanetErroCodeEnum.LIST_IS_EMPTY.getMessage();
            throw new SecretLanguagePlanetException(code, message);
        }

        return resultList;

    }

    /**
     * 获取返还信息
     *
     * @param resultList
     * @param questionId
     */
    private void getQuestionAndAnswerInfo(List<Map<String, Object>> resultList, String questionId) {
        QuestionAndAnswerInfo questionAndAnswerInfo = questionAndAnswerInfoRedisDao.getVoiceByQuestionId(
                Long.parseLong(questionId));
        UserCacheVo userCacheVo = userInfoCache.getUserCacheInfo(questionAndAnswerInfo.getAnswerUserId());

        Map<String, Object> map = new HashMap<>(0);

        map.put("questionId", questionAndAnswerInfo.getId());

        map.put("icon", userCacheVo.getIcon());

        map.put("nickName", userCacheVo.getNickName());

        resultList.add(map);
    }

    /**
     * 获取用户信息
     *
     * @param questionId
     * @param userId
     * @return
     */
    public Object getQuestionInfoById(long questionId, long userId) {
        //获取用户是否是vip
        UserCacheVo userCacheVo = userInfoCache.getUserCacheInfo(userId);
        if (userCacheVo.getIsVip() == 1 || userCacheVo.getIsSvip()==1 || userCacheVo.getIsPlatinumVip()==1) {
            //用户是vip 给信息
            long lasterQuestionId = secretLanguagePlanetInfoRedisDao.getNewestSecretLanguageInfoByUserId(userId);
            QuestionAndAnswerInfo obj = questionAndAnswerInfoRedisDao.getVoiceByQuestionId(questionId);

            //判断缓存中的问题id 是否相等，如果相等不入库，不更新缓存
            if (lasterQuestionId == questionId) {
                Map<String,Object> map = new HashMap<>(2);
                map.put("questionId",obj.getId());
                map.put("answerUrl",obj.getAnswerUrl());
                return map;
            } else {
                //入库并更新缓存
                insertAndUpdateCache(userId, questionId);

                secretLanguagePlanetInfoRedisDao.setNewestSecretLanguageInfoByUserId(userId, questionId);

                Map<String,Object> map = new HashMap<>(2);
                map.put("questionId",obj.getId());
                map.put("answerUrl",obj.getAnswerUrl());
                return map;
            }


        } else {
            long number = secretLanguagePlanetInfoRedisDao.getSecretLanguageNumbersByTimeAndUserId(LocalDate.now(), userId);
            if (number < NUMBERS) {
                QuestionAndAnswerInfo obj = questionAndAnswerInfoRedisDao.getVoiceByQuestionId(questionId);

                long lasterQuestionId = secretLanguagePlanetInfoRedisDao.getNewestSecretLanguageInfoByUserId(userId);

                if (lasterQuestionId == questionId || obj.getAnswerUserId() == userId) {

                    Map<String,Object> map = new HashMap<>(2);
                    map.put("questionId",obj.getId());
                    map.put("answerUrl",obj.getAnswerUrl());
                    return map;

                } else {
                    //入库，清缓存,
                    insertAndUpdateCache(userId, questionId);
                    //自增1
                    secretLanguagePlanetInfoRedisDao.setSecretLanguageNumbersByTimeAndUserId(LocalDate.now(), userId);

                    //更新最新偷听的数据
                    secretLanguagePlanetInfoRedisDao.setNewestSecretLanguageInfoByUserId(userId, questionId);

                    Map<String,Object> map = new HashMap<>(2);
                    map.put("answerUrl",obj.getAnswerUrl());
                    map.put("questionId",obj.getId());
                    return map;
                }

            } else {
                //抛异常,偷听次数已用完
                String code = SecretLanguagePlanetErroCodeEnum.NO_EAVESDROPPING_NUMBERS.getCode();
                String message = SecretLanguagePlanetErroCodeEnum.NO_EAVESDROPPING_NUMBERS.getMessage();
                throw new SecretLanguagePlanetException(code, message);
            }
        }

    }

    private SecretLanguagePlanetVo getSecretLanguagePlanetVo(UserCacheVo userCacheVo, QuestionAndAnswerInfo obj) {
        return new SecretLanguagePlanetVo()
                .setQuestionId(obj.getId())
                .setQuestionContent(obj.getQuestionContent())
//                .setAnswerUrl(obj.getAnswerUrl())
                .setAnswerTime(obj.getAnswerTime())
                .setAnswerMGrade(userCacheVo.getMGrade())
                .setAnswerVGrade(userCacheVo.getVGrade())
                .setAnswerUserId(userCacheVo.getUserId())
                .setAnswerUserAge(userCacheVo.getAge())
                .setAnswerUserAge(userCacheVo.getAge())
                .setAnswerUserSex(userCacheVo.getSex())
                .setAnswerUserIcon(userCacheVo.getIcon())
                .setAnswerUserNickName(userCacheVo.getNickName());
    }

    /**
     * 入库并更新缓存
     *
     * @param userId
     * @param questionId
     */
    private void insertAndUpdateCache(long userId, long questionId) {
        SecretLanguagePlanetInfo secretLanguagePlanetInfo = new SecretLanguagePlanetInfo()
                .setUserId(userId)
                .setQuestionId(questionId)
                .setCreateTime(LocalDateTime.now())
                .setCreateDate(LocalDate.now());
        secretLanguagePlanetInfoRedisDao.insertInfo(secretLanguagePlanetInfo);
    }

    /**
     * 获取最后偷听问题
     *
     * @param userId
     * @return
     */
    public Object getLasterQuestionInfoByUserId(long userId) {
        long questionId = secretLanguagePlanetInfoRedisDao.getNewestSecretLanguageInfoByUserId(userId);
        if (questionId == 0) {
            String code = SecretLanguagePlanetErroCodeEnum.NOT_LISTEN.getCode();
            String message = SecretLanguagePlanetErroCodeEnum.NOT_LISTEN.getMessage();
            throw new SecretLanguagePlanetException(code, message);
        }

        QuestionAndAnswerInfo obj = questionAndAnswerInfoRedisDao.getVoiceByQuestionId(questionId);

        UserCacheVo  answerInfo = userInfoCache.getUserCacheInfo(obj.getAnswerUserId());

        SecretLanguagePlanetVo secretLanguagePlanetVo = getSecretLanguagePlanetVo(answerInfo, obj);

        return secretLanguagePlanetVo;
    }

    /**
     * 重听
     * @param userId
     */
    public void getReplace(long userId) {

        secretLanguagePlanetInfoRedisDao.deleteListByUserId(userId);


    }

    public Object getClickById(Long questionId) {

        QuestionAndAnswerInfo obj = questionAndAnswerInfoRedisDao.getVoiceByQuestionId(questionId);

        UserCacheVo answerInfo = userInfoCache.getUserCacheInfo(obj.getAnswerUserId());

        SecretLanguagePlanetVo secretLanguagePlanetVo = getSecretLanguagePlanetVo(answerInfo, obj);


        return secretLanguagePlanetVo;

    }
}
